home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
CIS_GAME.ARJ
/
QANIM1.THD
< prev
next >
Wrap
Text File
|
1993-07-01
|
56KB
|
1,076 lines
__________________________ Subj: Compiled Sprites __________________________
Fm: Mark Betz/GD SL 76605,2346 # 109682
To: Mike Holt 100034,562 (X) Date: 17-Dec-91 13:08:37
Hi, Mike. Pointing SP to the video buffer and pushing the data is a neat
idea. If both the PUSH and MOV methods use immediate data then there's no
difference in speed, except that you have to set SP at the beginning of the
block. I'd guess from the timing that, as far as the processor is concerned,
PUSH is a MOV that always works with the same combination of registers as a
destination. Sprite compiling takes the idea a step further. The compiler
replaces the bitmapped data with a block of MOV instructions that use the
pixel values as immediate data. So if you had this line in an image:
07 08 23 51 5F 5E 4F 4F 3D 2C
The sprite compiler would turn it into this:
MOV [BX], 0807
MOV [BX+2], 5123
MOV [BX+4], 5E5F
MOV [BX+6], 4F4F
MOV [BX+8], 2C3D
It would produce the actual opcodes, not the pnemonics as I've shown them
above. To display this image you'd set the appropriate segreg to point to
a000h (I think the current compiler uses DS), put the offset of the first
pixel in BX, and make a far call to the first byte of the block. When John
first hinted at the idea I was skeptical because I was sure the bitmaps would
become too large. As it turned out the code generator was optimized so that
in some cases the increase in size was minimal. The increase is speed is
tremendous. There's code for all this in the lib (11) if you want to dive in.
It's by no means reached it's full optimization yet.
--Mark
...........................................................................
Fm: Dan R Corritore 70243,1110 # 188605
To: Bob Provencher 71621,2632 (X) Date: 17-Jul-92 02:21:38
>>...what the even faster method you mentioned. (was)
There isn't ONLY ONE faster method for doing animation. In fact, there are
many. One really neat idea is the one of Compiled-Sprites (which was
developed in this forum, although I don't know who by). The one I use is of a
Count/Skip method. At each line, my routine loads a value which holds the
amount of Count/Skip pairs in the line. Then, my routine loads the first
pair, adds the SKIP value to the Screen Pointer, then does a REP MOVSB. Then
it starts over until no more are left for the line, then goes to the next
line,etc. I use a variation of this now, but I used to use that method often.
Theres also another method which has the image in the Video Seg, and a 'Mask'
in normal memory. You load the mask and write it to the 'Map Mask Register'
or, if you are in EGA mode, the 'Bit Mask Register', then you transfer the
image to the right spot on screen, 4 pixels (or 8, in EGA) at a time. For
now, I've decided to use this strictly for animations which don't 'walk'
around the screen (like a tree being blown around by wind, for example),
because this particular method requires you to have it on a 4-pixel (or 8, in
EGA) boundary. You can do things to hide that,though.
Anyway, I've only done these methods in Assembly, because I doubt that you
can get the same speed in higher-level languages.
_Dan
...........................................................................
Fm: Mark Betz/GD SL 76605,2346 # 188801
To: Dan R Corritore 70243,1110 Date: 17-Jul-92 18:24:34
One note, Dan: compiling bitmaps wasn't developed in this forum. The topic
came up here when John Dlugosz mentioned the idea. In my typical relevance to
history I didn't think much of it <g>. Chris Lampton and David Stafford loved
the idea, and jumped on it. I produced a timing program, while Chris and
David produced compilers. David eventually produced a very fast compiler that
only increased the bitmap size by a factor of 1.x, if I remember correctly.
David also told Michael Abrash about the technique, and he mentioned it in a
recent column for DDJ. At the time, David mentioned to us that this technique
has been (is?) used in Windows, and is by no means new.
--Mark
...........................................................................
Fm: David Smith 71311,2334 # 271279
To: Mark Betz/Ass't SysOp 76605,2346 (X) Date: 31-Dec-92 21:14:03
I'm using compiled bitmaps with great success. If the only reason that you
want to clip the edges of the bitmaps is for the edges of the screen, you can
do like I've done. Make the screen memory wider and taller than the visible
area and just let the bitmaps hang off into the area that is not displayed.
...........................................................................
Fm: Serge Mathieu 71035,2771 # 273822
To: Mark Betz 76605,2346 (X) Date: 04-Jan-93 23:12:12
Mark,
As David Smith pointed out, the easiest way to clip compiled bitmaps is to
<< make the screen memory wider and taller than the visible area
and just let the bitmaps hang off into the area that is not displayed.>>
Of course, if your bitmaps are too big or if the reserved area has to be kept
to a minimum, you can cut them into small tiles and call the tiles that fit
in this area.
I'm sending you some thoughts I had on compiled bitmaps; some might be
good but most might just be inappropriate:
1- Save your bitmaps on disk in compiled format so that you won't have to
compile them at run time. It takes more space in memory and you cannot
perform rotation or apply any modification to bitmap.
Bytes are represented by MOV ES:[DI+Offset],Color
In order to blit them anywhere in video ram, DI contains start address of
bitmap; you set address before calling compiled bitmap:
MOV DI,Start_address
CALL Bitmap
2- You can blit to different screen widths or variable width ram buffers
if BX or another register is added to DI at end of each horizontal line:
MOV ES:[DI+Offset],Color (last pixel on this line)
ADD DI,BX (change line)
Offset is always calculated from beginning of each line, so most of the
time, it will be less than 256 if your bitmaps do not exceed this width.
You set address and destination width before calling compiled bitmap:
MOV DI,Start_address
MOV BX,Dest_Width
CALL Bitmap
3- Use compiled bitmaps in your ram buffer and use fast copy of unique
'dirty rectangles' to mode 13h or tweaked mode video ram. Buffer ram
doesn't need to be wider or taller to allow clipping: blit compiled bitmap
to another buffer the width and height of bitmap with preceding code and
copy clipped area back to main ram buffer. Of course, you have to fill
second buffer with transparent color before blitting and check for
transparency when copying it back to main buffer.
The idea is that clipping is less frequent than regular blitting and that
extra processing is equal to the size of clipped bitmap. You can perform
rotation or apply any modification to bitmap's copy before copying it back
to main ram buffer.
4- You can store your bitmaps in run-length encoded format. This way, you
can clip them and eliminate the check for transparency. This is an
alternative to compiled bitmaps.
ADD DI,Length_Trans_Color
MOV CX,Length_Pixels
REP MOVSB
LOOP
_________________________ Subj: RLE Encoded Bitmaps _________________________
Fm: Chris Lampton [GAMPUB] 76711,301 # 322845
To: KGliner 70363,3672 (X) Date: 29-Mar-93 09:25:08
Any reason you can't use RLE-encoding on the bitmap? That way, you can not
only skip entire _runs_ of transparent pixels in three or four instructions,
but you can move entire runs of _non_transparent pixels in a tight loop with
no transparency checking. The scheme I use in the Flights of Fantasy
simulator is to break the bitmap into two types of runs: transparent runs
(which consist of a single run-length byte with the high bit set) and
nontransparent runs (which consist of a run-length byte _without_ the high
bit set, followed by all the bytes in the run). This limits run-size to 128
bytes, but that's more than adequate. The speed increase over a naive
transparent blit was astonishing.
...........................................................................
Fm: Chris Lampton [GAMPUB] 76711,301 # 323922
To: KGliner 70363,3672 (X) Date: 30-Mar-93 22:03:40
Can you afford to double the size of the bitmap? (Not knowing how big the
bitmaps are, I don't know how many bytes that will cost you.) One idea I've
been toying with -- I think we may have discussed something similar -- is to
create a second byte map to accompany the pixel map. (Call it the "run map.")
Each byte of the run map array would correspond to a pixel in the pixel map
array. It contains the number of bytes remaining in the current transparent
or non-transparent run. For instance, if the pixel map looked like this:
117,39,251,8,17,0,0,0,0,0,0,0,0,0,201,125,99,148
then the corresponding run map would look like this:
5,4,3,2,1,9,8,7,6,5,4,3,2,1,4,3,2,1
There would be no compression, so you could easily locate a random position
in either map. By checking the value in the run map for that position, you
would know how many pixels remain after that point in the current transparent
or nontransparent run. By checking the pixel value, you would know if the
current run were transparent (zero pixel) or nontransparent (nonzero pixel).
You could then scale the run length, skip that distance (for a transparent
run) or initialize the tightest loop you can to grab the nontransparent
values (at scaled distances from one another) that remain in the run, with no
need for transparency checking.
Whether you actually _want_ to do that, of course, depends on how much extra
memory it would cost you to double the bitmap size and whether you could get
enough speed increase to be worth it. (And whether it's worth the hassle of
rewriting the code. <g>)
...........................................................................
Fm: Epic MegaGames 70451,633 # 326292
To: KGliner 70363,3672 (X) Date: 03-Apr-93 20:54:54
Kevin, store your bitmaps using RLE compression -- you'll save tons of space
and drawing time too. For example, if you're going to do a bit by bit
move..
lodsw ax ;Get byte (al) & run length (ah) from sprite
;bitmap
stosb al ;store it on screen
add dx,ah ;skip over rle (0=no run length, etc)
loop
And if you're really optimizing, you'll do this in CHAIN4 mode by first
moving all 4 planes together from video memory (ultra fast), then by going
through each of the four individual planes and moving lone pixels from system
memory.
Tim
(The art of bit blitting)
...........................................................................
Fm: KGliner 70363,3672 # 326490
To: Epic MegaGames 70451,633 Date: 04-Apr-93 03:08:33
Tim- I suspect you missed the context of the original message on
transparency. The problem involved scaling through scanlines of pixels at
variable rates (eg. sometimes 3.76 pixels at a time, sometimes .23 pixels,
etc), and there was also clipping at both ends. All of it was being done in
RAM-- none of it to the video screen. And the loops were all unrolled too.
In the end I felt the complexity of applying RLE encoding to indivdual pixel
runs (that didn't even end on single pixel boundaries) would take too much
time to implement under my schedule (and with questionable benefits since
most of the bitmaps were fairly complex).
Just the same, thanks for the reminder about how RLE works...
Kevin
__________________________ Subj: Animation Speed __________________________
Fm: Dan Corritore 70243,1110 # 324878
To: Bret Dixon 100117,3633 (X) Date: 01-Apr-93 16:17:34
Ok, first off, there are a few ways to do the sprites. (1)You can have them
stored in memory as 1 byte per pixel, or (2)you can have 4 runs of memory --
each run consisting of 'masks' that you use to write to a specific color
plane (R,G,B,I). (3) You could have the sprites stored in video memory. And
(4)then you can have them saved as 8 copies, each one being for every 8th
pixel. 1. Using the first approach , you'd use write mode 2, and write the
sprites vertically, from left to right. This would make the number of OUT's
to the ports equal to the width of the sprite. Also, although it is possible
to do it 2 pixels per byte, it's easier to do 1 pixel per byte. Speed is
moderate. 2. Using the second approach(4 runs-1 for each color plane), you'd
use write mode 0, and you'd start out each run with a different color plane
selected (R,G,B,I).. you'd then write 8 bits at a time to the display-- when
all 4 runs are finished, the colors would build the sprite. Using this method
would result in the most efficient use of memory, but it will make it tough
to write to anything other than byte-boundaries.(unless you have 8 copies,
each offset by 1 pixel) Speed is very good, provided that you are writing to
byte-boundaries. 3. You can have the sprites stored in (preferrably hidden)
video memory. You'd then use write mode 1 to transfer the sprite to the
location of your preference, 8 pixels at a time. This is pretty much the same
as using #2 approach. You will also need to have more copies stored in video
Ram to write to something other than a byte boundary. Speed is very good.
4.Using the last approach(having 8 copies), you'd use write mode 2, and you'd
write, possibly using REP MOVSB, the colors for every 8th pixel, by selecting
at the beginning of each copy a specific bit mask for the current spot. One
Note, though--using the last approach, you'd have to have 1 byte per pixel,
otherwise the REP MOVSB wouldn't be allowed. Speed is good. The above
techniques can be changed to allow transparency by doing the following:
1.for the first method, you'd just need to have a transparent color(usually
0) stored for each non-writeable pixel
2. for the second method, you'd need to have a 5th run of 8 pixels per byte,
which contains 1's for writeable pixels, and 0's for non-writeable pixels.
While doing the runs, you'd need to set the bit mask register for each write
using the 5th run's values.
3. you'd use the same as (2), by having a 5th run which describes 'visibile'
and 'non-visible' pixels, and setting the bit mask register before
transferring video memory to video memory.
4.you'd use the same approach for (1)
I'd recommend that you use either 1,3, or 4. Technique 2 could be used if you
don't have enough video memory to spare, though.
That about covers the techniques I've seen/used. There are also techniques in
which you have compressed sprites or run-length-encoding,etc., but they are
usually a variation of one of the above techniques (and usually technique 1).
Re:Overlapping-- just have some sort of ordering routine that will write the
sprites that are behind others first. The best way to do that would be to
look at where their feet are..
Whew! I hope I got that right!
_Dan
...........................................................................
Fm: rod lentz 71163,57 # 324955
To: Dan Corritore 70243,1110 (X) Date: 01-Apr-93 18:58:07
Bret -
Dan's answers are correct if your problem is simply the overhead
per frame, which you're trying to reduce. It doesn't answer the
other possible reading of your question, which would be that you're
having trouble keeping a constant frame rate regardless of scene
complexity.
To deal with this, you'll have to base your animation timings on
one of the pc's built-in clocks/timers. This is usually done off
system timer 0, which is used for system clock's "ticks since
midnight".
Using this, there are two ways to go. The first simply shoots
for a constant frame rate, by waiting in a loop, watching the timer,
to ensure a constant time from the beginning of one frame to the
beginning of the next. The second method is to try to get as much
animation into the available time. This is done by finding out how
long the previous frame took to image, and then scale all motion
for the next frame by that number.
This also nicely handles differences in machine speeds. I'm
amazed at the number of games (mostyly PD/FW/SW) that don't do this,
and so are unplayable on my 486/33 <argh!>.
- Rod
...........................................................................
Fm: Dan Corritore 70243,1110 # 325172
To: rod lentz 71163,57 (X) Date: 02-Apr-93 00:01:43
On regards of the timing issue, if he's using page-flipping, then he'll
already have the basic timers-the screen retraces.. these aren't the fastest
things to use, but they do keep the frame rate at a constant rate. Using one
of the 2 timers (well, on AT computers and up, he can use the secondary CMOS
timer) is another way to go too. Although I've only used the CMOS timer,
there's also the system timer, which can give you more precision in timing
(the reason I don't use it is because I have a music driver running on the
timer interrupt). There are so many ways to do things on PC's... it makes
some people go nuts! <g>
_Dan
...........................................................................
Fm: rod lentz 71163,57 # 325237
To: Dan Corritore 70243,1110 (X) Date: 02-Apr-93 02:23:11
Yep, the screen retraces will work, too - assuming you can always
generate a fresh one as fast as the card needs 'em. If not, you'd
always be delaying [unknown ?] multiples of the refresh rate. Also,
due to differences in refresh rates between different adapters &
monitors, this still won't be tying you to an absolute rate. I prefer
to go off a "real" clock, myself.
BTW, if you define your pages to always start on 256-byte
boundaries, you can safely flip pages without a retrace wait.
I've usually used the PIT's for clocking, but with fewer and
fewer pc/xt's out there/suitable for my apps, I've been using the
CMOS timer more. It's a heck of a lot easier, IMHO. Also, having
a music driver running off the PIT shouldn't preclude using it for
other timing, as well. In fact, I rarely use the PIT's interrupt
for this kind of delay; I usually just read the timer's counter.
As you say, so many ways to do it... the trouble is finding
one that's always "best" on all systems <g>.
- Rod
...........................................................................
Fm: Dan Corritore 70243,1110 # 325420
To: rod lentz 71163,57 (X) Date: 02-Apr-93 14:09:53
It's true that sometimes the page-flipping rate could change somewhat, but
I'd doubt that it would be too often that it would. And if you take a look at
a lot of games out there, you'll notice that they work at an acceptable speed
for _most_ of the time, until there's a lot of animation going on, and then
it slows down.. it's bearable, at least, to me. But basing when to do the
next page-flip according to the previous drawing/flipping time would be
silly, IMHO. But games and stuff which don't use page-flipping practically
require to have things going at a constant rate, possibly by looking at a
timer.. but I haven't seen/heard of too many that change their drawing rates
according to how much animation is going on in the screen..
And about the different refresh rates-- it was my understanding that
a card of a particular type (like VGA) should be about the same rate for all
those cards. I think for VGA it's 70Hz or something? Or possibly 60Hz?
<<Also, having the music driver running off the PIT shouldn't preclude using
it for other timing, as well.>>
Well, it will if you don't know the rate at which the timer interrupt
is called(and have no way of finding out)!! That's what my problem is--not
knowing the rate at which it is called.. it would screw up even microsecond
timing, at least, that's what I think Mark Betz said. (creator of the HTimer
class)
So, I'm using the CMOS timer.. and yes, it is easier to use. But it
is a possibility that the batteries could be dying.. leading to incorrect
timing, yes? Or is that only while the computer is off?
_Dan
...........................................................................
Fm: Randy @ Safari 71165,3600 # 325804
To: Dan Corritore 70243,1110 Date: 03-Apr-93 01:57:13
Apogee's FAST uses variable frame rate timing. Which gives an appearance of
the same frame rate on any speed machine. This is normally why Apogee FAST
games don't have stupendous sound or music, because FAST takes one of the
timers to manage variable rate animation.
I prefer the fixed frame rate cap method. People with slow machines are aware
that they have slow machines. ALL games run slow on slow machines (or you
play Apogee's no music FAST games).
Randy
...........................................................................
Fm: rod lentz 71163,57 # 325879
To: Randy @ Safari 71165,3600 (X) Date: 03-Apr-93 06:26:38
I've used the variable frame rate timing very successfully in some
animation [not games]; product intro screens, &c. Worked very nice
for a bit that needed to run on cga/ega/vga from pc/xt's to the top
of the line (386 at the time). Very well, considering this involved
a [simulated] rotating, scalable, texture-mapped sphere; better than
any other attempt I've seen. Sure, it would get kinda jerky on a
low-end machine with a high-res display, but always at a constant
rate.
Of course, if you have other stuf to do in the background, it's
pretty much out.
All in all, depends on the application.
Randy - I presume Apogee's FAST is a library they have; which
games use it ?
BTW, the CMOS battery should only affect it when the machine's
off; so, relative timing like we're talking about should always be
fine.
- Rod
...........................................................................
Fm: Randy @ Safari 71165,3600 # 326010
To: rod lentz 71163,57 (X) Date: 03-Apr-93 12:49:01
FAST is used in Pharoahs Tomb (oooh) and Monster Bash (Not yet released). It
was written by Gerald Lindsley (sp). Also, some SoftDisk games were done with
it like ScubaVenture.
It's not bad all in all but I still prefer the resource file & hand written
engine approach.
Randy
...........................................................................
Fm: rod lentz 71163,57 # 326521
To: Randy @ Safari 71165,3600 (X) Date: 04-Apr-93 04:56:51
Pharaoh's Tomb - ah, now I remember the mention. I was kinda torn
on that one; not a bad game, but the collision detection was horrible !
I think they mentioned that was related to FAST in the doc's; they
put a simple bounding box around everything, and if they overlap,
then... you die ! The big problem was, the bounding boxes were much
too liberal, and you were killed by objects that, as far as the
display was concerned, weren't very close. Not that that's a
requirement of the variable-action-per-frame technique that we've
been discussing.
As far as "resource file & hand written engine", I'm not entirely
sure what you mean. Personally, I prefer a "generic" engine, that
can be dropped into any app that fits; of course, that's tough to
do in state of the art games, and you often have to resort to custom
code for many parts.
- Rod
...........................................................................
Fm: Bret Dixon 100117,3633 # 326588
To: rod lentz 71163,57 Date: 04-Apr-93 10:24:37
Dan/Rod/Randy:
Bret again! Thanks for all the info.
First of all, Dan, thanks for the animation method info. I am currently using
your Method 1 (Write Mode 2, 1 memory byte per pixel). I am actually using 2
bytes per pixel but it is the same method. As you say, this has moderate
speed. I have found it is inadequate on slower
machines. Your Method 2 (write mode 0, writing the 4 colour planes) sounds
the best to me, although you did not advise the use of this method. You said
it is a problem writing short of a byte boundery. Do you think it would make
much difference to write to the boundery as over-kill just for programming
ease? Or would this impact performance?
Your Method 3 (Write mode 1, using Video memory) does not seem to be
feasible. This may be due to my limited understanding. If you use Video
memory, then you are limited to the Read/Write modes you have set. Write mode
1 is very limiting, and I don't understand how you can manipulate pixels in
video memory short of using the other methods you have suggested. In other
words, you seem to need one of the other methods to achieve Method 3. Your
Method 4 (Write mode 2, and 8 copies in memory), seems to be an unnecessary
exploitation of memory for the same performance you can get from Method 1. I
am explaining all this so that you can correct me if I have missed the point.
Anyway, my vote is for Method 2. If I'm wrong, please try and talk some sense
into me!
As for timing, Dan, Rod and Randy, I am currently reprogramming the System
Timer Channel 0 to pulse more frequently. This is because I found that 1
animation frame takes less than 18.2 of a second (the default programmed
pulse rate). I changed it to an arbitrary 400 pulses per second and found my
frame takes about 100 ticks (I am using the counter at 0040:006C). I needed
to slow the frame down to just over 200 ticks so that animation is not too
fast. But this is on a 386 33mhz.
Is this approach any good? What about using the CMOS time (I have never heard
of this approach). How does it work?
Also, I have found that if I deactivate the Turbo, my animation starts to
crawl across the screen. But in games like Gods by Bitmap Bros. deactivating
the Turbo has no apparent effect. What is going on? Is it possible to
deactivate the Turbo?
Any further info will be gratefully accepted, and thanks for all your help so
far!
Bret.
...........................................................................
Fm: Randy @ Safari 71165,3600 # 326733
To: rod lentz 71163,57 Date: 04-Apr-93 15:06:25
What I was referring to was the ability to create a "standard" game resource
file (sounds,maps, graphics) and utilize that file with any engine you write
as opposed to the FAST method where you develop the maps & chars in FAST, it
compiles them, then it gives you a game framework to build on.
The problem with FAST is that all FAST games look like FAST games, you know
what I mean? The character slides to a stop instead of stopping immediately,
big blocky graphics, no multi-planar scrolling backdrops (it uses PCX files
for the solid backdrop and then you can lay foreground tiles on top).
Randy
...........................................................................
Fm: Dan Corritore 70243,1110 # 327018
To: Bret Dixon 100117,3633 (X) Date: 04-Apr-93 21:47:29
About using method #2.. I advised against it because of the fact that it
would be a bit tougher to write to anything but a byte-boundary.. but
actually, it shouldn't be too hard to adjust for this.. you just need to
shift bits to the right, and allow for overflowing to the next byte, etc..
it's speed won't really change by much, as far as I'd be able to tell. But
when you add transparency to it, then your speed will start to decrease,
because you must do an OUT before each write (and also shift if on a non-byte
boundary)... actually, the speed shouldn't be too too bad (although you do 4
OUT's per every 8 pixels)..
<<Your Method 3 (Write mode 1, using Video memory) does not seem to be
feasible. This may be due to my limited understanding. If you use Video
memory, then you are limited to the Read/Write modes you have set.>>
Using video memory, you can use any read mode/write mode you darn well
want! Using method 3, you draw the sprites into a hidden( and unused) portion
of video memory on startup, then draw those sprites from then on using Write
mode 1. <<Your Method 4 (Write mode 2, and 8 copies in memory), seems to be
an unnecessary exploitation of memory for the same performance you can get
from Method 1..>>
About the memory requirements--actually, it's the same size as method
1... the 8 copies aren't really 'copies', but parts of the sprite split up..
I mean, every copy holds every 8th pixel in it. About the speed-- you can use
REP MOVSB's with it, if you play your cards right (either have
non-transparent figures or run-length-encoding (RLE) compression).. also,
only 8 OUT's are necessary
Now.. let me revise my view on the others.. Method 1 is the easiest,
and is portable (but who cares about portability!?? <g>). It's speed is 'good
enough', but not for everybody. I have a RLE-like implementation of Method 1
which seems to work pretty darn fast, though. Method 2-- easy to use, if you
are going for byte-boundaries only. And about using byte boundaries-- that's
not too limiting, just remember to have some animation to make it look as
though it's not using byte boundaries. Method 2 isn't that bad, though, and I
don't know why I didn't recommend it, but I'd guess I said that because I'm a
256-color 'tweaked' mode programmer now, and don't like 16-color anymore! <g>
Method 3-- well, method 2 can replace it, but it requires more writes (method
2- 8 pixels= 4 writes, method 3- 8 pixels= 1 read, 1 write).. and remember,
the less you access video ram the better! But I've never used video ram-based
sprites myself.. partly because they are limiting in a way(byte-boundary
only.. unless multiple copies). I'd say to use write mode 1 for
drawing/saving backgrounds or whatnot, since backgrounds don't change.. it
would also be good for 'erasing' sprites. So I'd guess the order of speed for
these would be(in best to worst order) : 4( 8 copies),3 (vram to vram),2(4
copies),1(single copy) . If it was up to me, I'd use method 4 (for ease of
use/speed), or method 1 (for ease of use).. and if worst came to worst method
2 (a bit too complicated).
Questions? :)
_Dan
...........................................................................
Fm: rod lentz 71163,57 # 327100
To: Randy @ Safari 71165,3600 (X) Date: 04-Apr-93 23:44:11
I know what you mean about all FAST games looking the same.
However, having a generic engine also has its appeal. The problem
is coming up with a complete and flexible enough design that you
can handle everything; and within the constraints of current hardware.
And of course, I'm also a programmer <g>; I don't just want to
use a CASE tool.
No perfect solution, I guess :).
About using the system timer - I don't quite understand why
everybody seems to reprogram it, and use the interrupt. Sure, that's
great if you need something in the background, but for foreground
tasks I find it easier to just read the current value from the chip.
For longer delays, combine this with the system's tick counter.
Anybody care to shed some light for me ?
- Rod
...........................................................................
Fm: Ed. Mueller 70441,3720 # 343766
To: ALL Date: 28-Apr-93 22:12:24
Let's talk hypothetically. Lets say I have a character which has 100
distinct frames of animation whose sizes vary from roughly 50x50 to as big as
100x50. All together we're talking roughly .5 MB worth of images (256 color
mode). Naturally, I'd need access to each image quickly since we're doing
heavy duty animation. The 1 MB limit on DOS does not leave much room for any
program to control the images. Also, I'd be using compiled sprites such that
each image would have to reside in the 1 MB address space so that it could be
called to draw the image. What are my options and what are the tradeoffs?
My ideas are as follows:
- Use some type of DOS extender or XMS. Problem is each sprite must be
copied to conventional RAM to be executed (right?). Would that overhead
be too much?
- Use a 32-bit compiler. Not such a great choice because I'd be using
Borland C++ 3.1. Is there anyway for it to generate 32-bit code?
Let me hear your ideas. Thanks again.
...........................................................................
Fm: Maxx 71102,1124 # 344034
To: Ed. Mueller 70441,3720 (X) Date: 29-Apr-93 08:53:53
I'm not sure about BC3.1 (I know it has an option for 286 codes and 386
codes) I do know that Watcom C will do 32 bit , but it's a little pricy..
Just as a hypothetical suggestion, how about having this massive sprite be
compressed in memory, then expanded when drawn? (Using a fast decompressor of
course) Just an idea..
...........................................................................
Fm: E. Pinnell [CyberSim] 70031,435 # 344064
To: Ed. Mueller 70441,3720 (X) Date: 29-Apr-93 10:07:54
Ed,
Get a compiler that creates 32 bit DPMI compliant code. If you go for a
DOS extender (a la Phar Lap), this will work too but they cost more (some
require royalties).
Eric Pinnell
...........................................................................
Fm: Mark 'SAM' Baker 100025,444 # 344148
To: Ed. Mueller 70441,3720 (X) Date: 29-Apr-93 12:49:13
Don't store the entirety of each frame; only the differences from the last
frame displayed. Then only the first frame needs to be stored in a full state.
This will not only reduce the overhead required for storing frames 2 to 100;
but can also speed up the drawing of the frame.
Mark
...........................................................................
Fm: VOR Technologies Inc 71333,134 # 344220
To: Ed. Mueller 70441,3720 (X) Date: 29-Apr-93 14:53:30
Ed,
Are the frames your storing transitions from one another? If so you can come
up with a simple diffing agolrythm that will store the changes from frame to
frame and then use a piece of code that will just plot the appropriate
changes pixels between each frame. This offers very fast and smooth
animation. And wil decrease the overall size a lot of the transitions are
gradual as in a normal animation.
Chris Eisnaugle Vor Technologies Inc.
...........................................................................
Fm: Steve Salter 71732,3126 # 344754
To: VOR Technologies Inc 71333,134 (X) Date: 30-Apr-93 07:29:53
|Are the frames your storing transitions from one another? If so you can come
up |with a simple diffing agolrythm that will store the changes from frame to
frame |and then use a piece of code that will just plot the appropriate
changes pixels |between each frame. This offers very fast and smooth
animation. And wil |decrease the overall size a lot of the transitions are
gradual as in a normal |animation. | |Chris Eisnaugle Vor Technologies Inc.
I think I missed the start of this thread...are you talking about animating
sprites or background bitmaps? This sounds very intriguing.
Steve
__________________________ Subj: Animation Timing __________________________
Fm: Cameron Grant 100031,2265 # 146200
To: Karl R Corritore 70243,1110 (X) Date: 20-Mar-92 16:27:45
In my game DOMINATION, (the current version 1.2, unreleased as yet...) I'm
using the vertical retrace irq to run some 8 layer 70Hz paralax scrolling
stars and colour cycling in the background...It looks pretty impressive!!!
I just took a look in kliewer's book (or whatever his name is <g>) at the
vertirq2 source, and then translated the bits I needed into BASM in TP6! Was
extremely surprised when it worked perfectly first time tho'!
Dunno what happened to that response...(!)
I didn't find it too difficult to write a vertical retrace int handler, I
just look in kliewer's book at the VERTIRQ2.ASM source code, and appropriated
bits of it...
...........................................................................
Fm: Activision/Infocom 76004,2122 # 188032
To: Mark Betz/GD SL 76605,2346 (X) Date: 15-Jul-92 13:12:08
We just shipped LGOP2, a very complex game that has alot of tasks tied to the
timer interrupt. Like a 8KHz task that pumps out 4 channel digital audio and
forks to:
1. A Cursor and mouse/keyboard/joystick task.
2. The audio decompression task.
3. The Midi Task.
4. The clock tasks.
5. Fifo tasks for various devices.
6. The 18.2Hz system task.
It also had a Mac-style memory manager that moved stuff around.
Would up renting a Periscope IV just to fix problems.
Even after all that, I've discovered...
1. Errant sound cards (1/1000) can take a very long time to acknowledge a
write to a hardware register.
2. Some BIOS/PC systems actually mess up the MOVE.SW direction flags. No
lie.
3. There are non-register compatable VGA cards out there.
4. QEMM and other 386 managers slow down interrupts alot.
5. Animation optimization is great, but you'll spend all of your time writing
to video memory anyway .... it's very slow.
Not fun, but instructional...
...........................................................................
Fm: Serge Mathieu 71035,2771 # 193923
To: Dan R Corritore 70243,1110 (X) Date: 31-Jul-92 15:53:53
Dan,
How do you do your timing for animation? I have theses solutions:
1- Hook yourself on vertical refresh of video card for 70 ticks/sec 2- Hook
yourself on INT 08 for 18 ticks/sec 3- Hook yourself to sound driver to about
10,000 ticks/sec
......???
Serge Mathieu
...........................................................................
Fm: Dan R Corritore 70243,1110 # 193965
To: Serge Mathieu 71035,2771 (X) Date: 31-Jul-92 17:03:29
Well, the fact is, I was going to try each one of the ideas you tried (except
#3, which I never heard of doing) . Hooking yourself into the vertical
interrupt is a great idea, but the only thing is, not every computer will
support this.
The timer interrupt is a possibility, and it can be programmed to run at a
certain pace, too. I was going to run the timer interrupt at 70 times per
second, and have the timer routine check a variable to see if I was done
writing to a page, and then flip pages at each vertical interrupt. This would
also require the animation drawing routine to check this variable to see if I
changed pages yet before it draws the screen(which ends up in a Loop
anyways)..And since there is a _CLI_ instruction, there is the possibility
that the timer could be knocked off a bit.. And, since some sound drivers and
stuff run off the timer interrupt, it becomes less desirable to do this.
I do my drawing onto a 'hidden' page, so that it doesn't need to be
timed..its just the page flipping that needs to be timed. So far, I've been
doing the combination of waiting for Vretrace, then changing pages, then
waiting for a Non-retrace. Then I do some processing, and erase and write the
new sprites, then flip pages again, and so on..
So far, it works good..but sometimes, there is a slight flash in the screen,
so I know the timing is off a bit, but its bearable for now..
_Dan
...........................................................................
Fm: Randy @ Safari 71165,3600 # 344049
To: Dan Corritore 70243,1110 (X) Date: 29-Apr-93 09:32:45
re: Space Chase
->development system
the new system was being written while Game 1 was being done, there just was
not time to redo all the levels.. Games II and III are done with the
development system and are much more vivid with walk-behind trees, flowing
grass, c-thru chain-link fences, etc...
->my butt
Maybe _your_ code can only do 50fps ;) No really, it's possible on a 12Mhz
80386 with a 16-bit video card to get 90-105 fps using the FAST method with
no parallax backgrounds. 8-bit cards will usually do 58-70 fps depending on
the card and machine but the engine knows which one it's using and makes the
necessary changes to run faster. Heck, it does 157fps on a 33Mhz 386 with
16-bit video card.. that's 160 scan lines, not 200 (at 200 it's 131 fps on a
386-33 w/16bit card)
->good luck <on Sonic>
wouldn't that be an incredible undertaking.. the only drawback is that it
wouldn't have the multiple scrolling backdrops like Sonic.. That's just not
possible on low-end machines at high speeds. I don;t think we'll be doing
Sonic anytime soon..
Randy
...........................................................................
Fm: Dan Corritore 70243,1110 # 344168
To: Randy @ Safari 71165,3600 (X) Date: 29-Apr-93 13:14:31
Well, your new system sounds pretty good.. I hope you're going to use that
for your first game!
<<Maybe _your_ code can only do 50fps ;) No really, it's possible on a 12Mhz
80386 with a 16-bit video card to get 90-105 fps using the FAST method with
no parallax backgrounds. 8-bit cards will usually do 58-70 fps depending on
the card and machine but the engine knows which one it's using and makes the
necessary changes to run faster. Heck, it does 157fps on a 33Mhz 386 with
16-bit video card.. that's 160 scan lines, not 200 (at 200 it's 131 fps on a
386-33 w/16bit card)>>
The fact is, you can't go faster than the scanning rate of the video card and
monitor.. currently, there are no 105 HZ monitors _or_ video cards out there
(unless I'm missing something.. perhaps that new XGA card?<g>) Actually, it
is possible to write to the video adapter at 100+ fps, it's just the user
will only see maybe half of that. It's no use to go any faster than the scan
rate of the cards/monitors, if that's what you are doing.(which you must be
doing if you're getting reports of 100+ fps!!)
Oh, no parallax scrolling on Sonic? Sure, I can see doing the Sega Game Gear
version of Sonic.. no problem! :)
_Dan
...........................................................................
Fm: Randy @ Safari 71165,3600 # 344195
To: Dan Corritore 70243,1110 (X) Date: 29-Apr-93 13:51:40
True.. you cannot update faster than the scan rate.. the point is to get the
game as fast as possible, then slow it down artificially to achieve a
standard frame rate... I think 40fps is more than enough
Randy
_____________________ Subj: Compiled Animation Sequence _____________________
Fm: Mark Betz/GD SL 76605,2346 # 216698
To: all Date: 23-Sep-92 17:30:55
Hi, guys. I want to poll you for some thoughts on the design of an special
animation engine. If you've been through the libs you may be familiar with
the idea of bitmap compilation, which was resurrected here sometime back. In
case you haven't, I'll briefly recap: The standard method of displaying a
bitmap involves a loop of instructions to move bytes or words from one place
in memory to another place in display memory. As we all know, one of the
standard techniques of optimization is loop unrolling. Compiled bitmaps are
the ultimate unrolled loop. When a bitmap is compiled the image data is
scanned, and the compiler outputs a series of opcodes with the image bytes as
immediate data. For example, if a bitmap contains the bytes 223 227 226, the
compiler creates something that looks like this MOV ES:[110],223 MOV
ES:[111],227 MOV ES:[112],226, etc. Runs of transparent bytes and the line
wrap are encoded in the index to each MOV instruction. To display a bitmap
you simply call it! This is arguably the fastest possible way to display a
bitmap on the PC, and amazingly enough, it doesn't result in huge chunks of
compiled code. See CTRANS.ZIP, and Dave's Bitmap Compiler in LIB 11 if you're
interested.
So we can compile individual frames of an animation sequence. What I want to
do is add to that the capability for delta-frame compression. Delta frame
compression is a method which saves only the changes between frames in a
sequence. I'm thinking of a "delta-frame compiler" which would compile _all_
of the frames in a sequence into a single delta frame compressed sequence.
The compilation part is pretty straightforward, once you've performed the
delta analysis. The part that puzzles me is frame rate control. I dare say
that if I created a compiled sequence and called it would be too fast to see.
So, how to control display rate in this instance? I'm leaning toward a
call-back function which would be called at the end of each frame. It could
simply return, or implement a delay loop. What do you think?
...........................................................................
Fm: Jaimi 71700,1202 # 216774
To: Mark Betz/GD SL 76605,2346 (X) Date: 23-Sep-92 20:52:38
Mark,
Since you're going to have to slow it down, why do it? It seems that since
you want to compress the animation, what is mattering is not speed (which is
limited by the speed of your bus and your VGA anyway) but size, and a
compiled bitmap would take 3 times as much space as a data bitmap. Also, is
it really truly faster than doing REP STOSW? If you used data, you could
define a structure that held the x,y,w,h of each "frame" (in quotes because
it could be just a partial frame) and also the length of time that it was
supposed to be displayed before passing on to the next frame. Then a vary
small routine could be written that would basically just store it to the
screen, and then wait to return. all you would have to do is call it in a
loop. You asked what I thought! I just didn't think it would take this much
space!
...........................................................................
Fm: Mark Betz/GD SL 76605,2346 # 216800
To: Jaimi 71700,1202 (X) Date: 23-Sep-92 21:54:50
Well, three times larger is a pathological case, complex bitmap with no
transparency. I think the best David got was in the neighborhood of 1.4 times
the data size. It is definitely faster than a rep stosw. By several orders of
magnitude. All of the data is immediate data, and there is no address
calculation. The raw bus transfer rate doesn't change, but a lot of other
overhead is removed. Take a look at the test programs in lib 11.
The reason for doing it is that the compiling, combined with the delta
compression, should produce animations sequences which are both smaller, and
much faster than they would be done the usual way. Suppose you were doing an
arcade-like game, and you had a character sprite with various distinct
motions: run, crouch, jump, swing, etc. Each motion could be compiled into an
animation sequence. Then the entire animation process is a simple matter of
calling the proper motion. Since the compiled sprites are very fast, you can
use a lot of frames for very smooth and fast sprite actions.
...........................................................................
Fm: Dan R Corritore 70243,1110 # 216826
To: Mark Betz/GD SL 76605,2346 (X) Date: 23-Sep-92 22:57:09
I'd like to say that the delta frame compression is a great idea..Deluxe
Paint Animation uses it, and I'll most likely use it too, but _only_ for
pre-ordered animations. What you are saying about having a sprite which can
run,crouch,jump, etc. be a compiled delta-frame-compression thingy :-) is not
a good idea if you are planning on having more than one color as a background
color, or having the sprite be able to walk behind masks, or having the
sprite be able to walk partially off the screen(or window)..compiled sprites
are basically not good for realistic applications in my eyes. On the other
hand, having compiled-delta-frame-compression to be used on pre-ordered
animations (an opening sequence for a game, perhaps) is a pretty neat idea.
...........................................................................
Fm: yngvi 76703,3046 # 216992
To: Mark Betz/GD SL 76605,2346 (X) Date: 24-Sep-92 13:20:27
I worked on a project using delta compilation about 6-7 years ago -- we did
traffic accident simulations to support expert witnesses in trial testimony.
Our system was pretty primitive -- we were constrained by existing technology
among other considerations. (the animation was all CGA). We did manage to
get up to about 10 sec of animation into a 300K system. I wrote an article
about it for Computer Language magazine at that time.
It's been awhile, but I think the timing was controlled during the delta
calculations. The frame rate was one of the set up parameters. The playback
program could run at either the 'real' rate or several faster or slower rates.
This turned out to be useful for the experts, since they could speed up, slow
down, step thru or even freeze the action.
Steve
...........................................................................
Fm: Bob Provencher 71621,2632 # 216807
To: Mark Betz/GD SL 76605,2346 (X) Date: 23-Sep-92 22:32:10
Hi Mark,
That sounds like a good idea to me. I can think of a few ways to
handle the frame rate. At the end of each frame insert an instruction that
loads the address of the start of the next frame into a register and
returns. Something like this in pseudo assembler (remember I don't know
assembler that well)
MOV ES:[110],223
MOV AX,[IP+?] ; whatever the correct offset would be to
; the start of the next frame...
RET
MOV ES:[0],86 ; here
...
MOV AX,0 ; last frame
Then in the timer interrupt handler you could do something like this:
MOV AX,[NEXTFRAME] ;
??? ; test here for zero
??? ;
CALL AX ; if there is such an instruction
MOV [NEXTFRAME],AX ; save the next frame's start
IRET ; return
If you implemented a callback function at the end of each frame it might be
kind of difficult to control the delay loop to have the same delay for each
frame. This way you're guaranteed to have frames equally spaced. Does this
make sense?
Bob
...........................................................................
Fm: Mark Betz/GD SL 76605,2346 # 217074
To: Bob Provencher 71621,2632 (X) Date: 24-Sep-92 18:15:37
Sort of, yes. However, even spacing might not always be desireable. Consider
an action, such as jumping: various individual motions might require
different timings to make the sequence look realistic. I was thinking that
you could use a callback function, and then point to a table of delays right
before calling the animation. Everytime the callback function was executed it
would load the next delay value and wait that long before executing the next
frame. This would give quite a bit of flexibility over frame timing. What do
you think?
___________________________ Subj: Game Generators ___________________________
Fm: Fire Bird 71045,2014 # 198831
To: all Date: 11-Aug-92 20:58:43
Are there any game generation systems out there? I know Sierra made their
own, and so did a lot of other gamming companies.
I think it would be fun to design a game and chalenge everbody.
Eg one with two different parts.
Game design (create screens, dialog, maps, sound, etc)
produces data files
Game runtime (requires data)
produces fun
I wonder...Hmmm...shared gaming...Multiuser...compuserve messages...
...........................................................................
Fm: Serge Mathieu 71035,2771 # 198907
To: Fire Bird 71045,2014 Date: 11-Aug-92 22:34:38
Sierra hired a programmer for a full year just to program a game interpreter
a couple of years ago. This is NOT a simple task; you have to design
everything so your generator won't become obsolete if you want to add
features like AI, OOP, automatic sprite handling, garbage collection, events,
etc...
Serge Mathieu
...........................................................................
Fm: Mark Betz/GD SL 76605,2346 # 199188
To: Fire Bird 71045,2014 Date: 12-Aug-92 18:40:32
Hi, Carl. Welcome! There are certainly some game construction engines
available. In LIB 2 here you'll find both the AGT Adventure Game construction
kit, and DCGames CRPG construction kit. I've heard lately that the new
version of DCG is really superb. Also, on the commercial end, Interplay
released the Bard's Tale Construction Set. I don't know much about it. It
would be interesting to design a game generation system. Most of us here
approach that only in that we design many tools for our own use, such as
frame editors, font editors, palette utilities, etc.
--Mark
__________________________ Subj: Shrinking Sprites __________________________
Fm: John Dlugosz [ViewPoint] 70007,4657 # 330492
To: Mark Hula 100047,110 (X) Date: 10-Apr-93 12:28:07
That is a complex subject. One way is to remove extra rows and cols. Upon
removing, either toss out or merge it with an adjecent row, depending on the
nature of the image. Another way is to take a clump of pixels and average
them together. Easy to reduce to 1/n where n is an integer, but harder to
reduce by an arbitrary amount. Also this gives you an all new palette.
<<My question is how do I work out with column or row to remove inorder to
shrink the object>> Same way you draw lines and decide when to "jag".
Picture a rectangle MxN where M is the old number of rows and N is the new.
Look at a diagonal line drawn in that rectangle. It it gives a plot of which
rows to keep! Just take one of the rows from each "run" of a horizontal
line. One row for each jag, IOW.
Rotating by 360 degrees is simple-- just a null operation.
--John